<template>
  <div class="text-xs">
    <div class="flex items-start py-1 cursor-pointer transition-colors hover:bg-gray-50 rounded group" @click="toggleExpand">
      <span v-if="hasChildren" class="w-4 flex-shrink-0 text-gray-500 text-xs mt-0.5">
        <i :class="expanded ? 'el-icon-caret-bottom' : 'el-icon-caret-right'"></i>
      </span>
      <span v-else class="w-4 flex-shrink-0"></span>

      <div class="flex-1 min-w-0 flex items-start gap-2">
        <span class="text-blue-600 font-medium flex-shrink-0" v-html="highlightText(variable.name, searchKeyword)"></span>
        <span class="text-teal-600 text-[11px] flex-shrink-0 mt-0.5" v-html="highlightText(formatType(variable.type), searchKeyword)"></span>

        <!-- 值显示区域 -->
        <div class="flex-1 min-w-0">
          <!-- 编辑模式 -->
          <div v-if="editing" class="flex flex-col gap-1" @click.stop>
            <div class="flex items-center gap-1">
              <input
                ref="editInput"
                v-model="editingValue"
                type="text"
                class="flex-1 px-2 py-1 text-xs border border-blue-400 rounded focus:outline-none focus:border-blue-600"
                :disabled="saving"
                @keydown="handleEditKeydown"
              />
              <el-button
                type="primary"
                size="mini"
                :loading="saving"
                @click.stop="saveEdit"
              >
                保存
              </el-button>
              <el-button
                size="mini"
                :disabled="saving"
                @click.stop="cancelEdit"
              >
                取消
              </el-button>
            </div>
            <span v-if="editingError" class="text-red-500 text-xs">{{ editingError }}</span>
          </div>
          <!-- 长值展开模式 -->
          <div v-else-if="!valueExpanded && isLongValue" class="flex items-center gap-1">
            <span
              class="text-orange-700 truncate"
              :class="{'cursor-text': isEditableType, 'bg-green-100': modifiedRecently}"
              @dblclick.stop="startEdit"
              :title="isEditableType ? '双击编辑' : ''"
              v-html="highlightText(formatValue(variable), searchKeyword)"
            >
            </span>
            <el-button
              type="text"
              size="mini"
              class="!text-gray-400 hover:!text-primary-500 !p-0 !h-auto opacity-0 group-hover:opacity-100"
              @click.stop="valueExpanded = true"
            >
              <i class="el-icon-arrow-down text-xs"></i>
            </el-button>
          </div>
          <!-- 长值完全展开模式 -->
          <div v-else-if="valueExpanded" class="flex flex-col gap-1">
            <div
              class="text-orange-700 break-all whitespace-pre-wrap max-h-48 overflow-y-auto bg-gray-50 p-2 rounded border border-gray-200"
              :class="{'cursor-text': isEditableType}"
              @dblclick.stop="startEdit"
              :title="isEditableType ? '双击编辑' : ''"
              v-html="highlightText(formatValue(variable), searchKeyword)"
            >
            </div>
            <el-button
              type="text"
              size="mini"
              class="!text-gray-400 hover:!text-primary-500 !p-0 !h-auto self-start"
              @click.stop="valueExpanded = false"
            >
              <i class="el-icon-arrow-up text-xs"></i> 收起
            </el-button>
          </div>
          <!-- 普通显示模式 -->
          <span
            v-else
            class="text-orange-700"
            :class="{'cursor-text hover:bg-gray-100 px-1 -mx-1 rounded': isEditableType, 'bg-green-100': modifiedRecently}"
            @dblclick.stop="startEdit"
            :title="isEditableType ? '双击编辑' : ''"
            v-html="highlightText(formatValue(variable), searchKeyword)"
          >
          </span>
        </div>
      </div>
    </div>

    <div v-if="expanded && hasChildren" class="ml-4 border-l border-gray-300 pl-2">
      <variable-tree-node
        v-for="(child, index) in variable.children"
        :key="index"
        :variable="child"
        :parent-path="variablePath"
        :search-keyword="searchKeyword"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'VariableTreeNode',
  inject: {
    getCurrentGoroutineId: {
      default: () => () => -1
    },
    getCurrentFrameIndex: {
      default: () => () => 0
    },
    setVariableValue: {
      default: null
    }
  },
  props: {
    variable: {
      type: Object,
      required: true
    },
    parentPath: {
      type: String,
      default: ''
    },
    searchKeyword: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      expanded: false,
      valueExpanded: false,
      editing: false,
      editingValue: '',
      editingError: '',
      modifiedRecently: false,
      saving: false
    }
  },
  computed: {
    // 计算当前变量的完整路径
    variablePath() {
      const varName = this.variable.name || ''

      // 如果变量名为空，检查是否有索引（数组/切片元素）
      if (!varName.trim()) {
        // 对于数组/切片元素，dlv 可能不提供名称，但这些变量无法通过表达式访问
        // 我们返回空字符串，表示无法构建有效路径
        return ''
      }

      if (this.parentPath) {
        return `${this.parentPath}.${varName}`
      }
      return varName
    },
    hasChildren() {
      return this.variable.children && this.variable.children.length > 0
    },
    isLongValue() {
      const val = this.formatValue(this.variable)
      // 如果值超过 50 个字符，认为是长值
      return val && val.length > 50
    },
    // 判断是否为可编辑的基本类型
    isEditableType() {
      const kind = this.variable.kind
      // 可编辑的类型：Bool(1), Int/Uint系列(2-13), Float系列(14-15), String(24)
      // Bool=1, Int=2, Int8=3, Int16=4, Int32=5, Int64=6, Uint=7, Uint8=8, Uint16=9, Uint32=10, Uint64=11, Uintptr=12, Complex64=13, Complex128=14, Float32=15, Float64=16, String=24
      return kind >= 1 && kind <= 16 || kind === 24
    }
  },
  methods: {
    toggleExpand() {
      // 只允许切换已有子元素的展开状态
      if (this.hasChildren) {
        this.expanded = !this.expanded
      }
    },

    formatType(type) {
      if (!type) return ''
      // 简化类型显示
      return type.replace(/^.*\./, '')
    },

    formatValue(variable) {
      if (!variable) return ''

      const val = variable.value
      const kind = variable.kind

      // kind 枚举值：
      // 1: Bool, 24: String, 17: Array, 21: Map, 22: Ptr, 23: Slice, 25: Struct
      const KIND_BOOL = 1
      const KIND_STRING = 24
      const KIND_ARRAY = 17
      const KIND_MAP = 21
      const KIND_PTR = 22
      const KIND_SLICE = 23
      const KIND_STRUCT = 25

      // 根据类型格式化值
      if (val === undefined || val === null) {
        return 'nil'
      }

      if (kind === KIND_STRING) {
        // 字符串值，保留原始格式
        return `"${val}"`
      }

      if (kind === KIND_BOOL) {
        return val ? 'true' : 'false'
      }

      if (variable.children && variable.children.length > 0) {
        // 对于复合类型，显示元素数量或内容
        if (kind === KIND_SLICE || kind === KIND_ARRAY) {
          return `[${variable.len || 0}]`
        }
        if (kind === KIND_MAP) {
          return `{${variable.len || 0}}`
        }
        if (kind === KIND_STRUCT) {
          // 对于结构体，如果有值就显示值，否则显示 {...}
          return val || '{...}'
        }
        if (kind === KIND_PTR) {
          // 对于指针，如果有值就显示值，否则显示地址
          return val || variable.addr || '0x0'
        }
      }

      // 对于其他类型，限制显示长度
      const strVal = String(val)
      return strVal
    },

    // 开始编辑
    startEdit() {
      if (!this.isEditableType || !this.setVariableValue) return

      // 对于字符串类型,给出警告提示
      const kind = this.variable.kind
      if (kind === 24) { // String
        this.$confirm(
          '由于 Delve 调试器的限制，修改字符串类型的变量可能会失败。\n\n' +
          'Delve 不支持修改需要内存分配的类型（如字符串、切片、映射等）。\n\n' +
          '您可以尝试修改，但如果失败，这是 Delve 的已知限制。\n\n' +
          '是否继续尝试修改？',
          '提示',
          {
            confirmButtonText: '继续修改',
            cancelButtonText: '取消',
            type: 'warning'
          }
        ).then(() => {
          this.doStartEdit()
        }).catch(() => {
          // 用户取消
        })
        return
      }

      this.doStartEdit()
    },

    // 实际执行开始编辑的逻辑
    doStartEdit() {
      this.editing = true
      // 获取原始值（去掉引号等格式化符号）
      const kind = this.variable.kind
      let rawValue = this.variable.value

      if (kind === 24) { // String
        // 字符串保留原值即可
        this.editingValue = rawValue || ''
      } else if (kind === 1) { // Bool
        this.editingValue = rawValue ? 'true' : 'false'
      } else {
        // 数字类型
        this.editingValue = String(rawValue || '')
      }

      this.editingError = ''

      // 聚焦到输入框
      this.$nextTick(() => {
        const input = this.$refs.editInput
        if (input) {
          input.focus()
          input.select()
        }
      })
    },

    // 取消编辑
    cancelEdit() {
      this.editing = false
      this.editingValue = ''
      this.editingError = ''
    },

    // 验证并保存编辑
    async saveEdit() {
      if (this.saving) return // 防止重复提交

      const kind = this.variable.kind
      let newValue = this.editingValue.trim()

      // 验证输入
      if (kind === 1) { // Bool
        if (newValue !== 'true' && newValue !== 'false') {
          this.editingError = '布尔值只能是 true 或 false'
          return
        }
      } else if (kind >= 2 && kind <= 16) { // 数字类型
        if (kind === 15 || kind === 16) { // Float32, Float64
          if (isNaN(parseFloat(newValue))) {
            this.editingError = '请输入有效的浮点数'
            return
          }
        } else if (kind >= 13 && kind <= 14) { // Complex64, Complex128
          this.editingError = '暂不支持编辑复数类型'
          return
        } else { // 整数类型
          if (!newValue.match(/^-?\d+$/)) {
            this.editingError = '请输入有效的整数'
            return
          }
        }
      } else if (kind === 24) { // String
        // 字符串类型允许空值
        // 为字符串添加引号（dlv API 需要）
        newValue = `"${newValue}"`
      }

      // 设置保存状态
      this.saving = true
      this.editingError = ''

      try {
        const goroutineID = this.getCurrentGoroutineId()
        const frameIndex = this.getCurrentFrameIndex()

        const result = await this.setVariableValue(
          this.variablePath,
          newValue,
          goroutineID,
          frameIndex
        )

        if (result.success) {
          // 更新本地值
          if (kind === 1) {
            // 布尔值
            this.$set(this.variable, 'value', newValue === 'true')
          } else if (kind === 24) {
            // 字符串值（newValue 已包含引号，需要去掉引号存储）
            const rawStringValue = this.editingValue.trim()
            this.$set(this.variable, 'value', rawStringValue)
          } else {
            // 数字类型直接存储
            this.$set(this.variable, 'value', newValue)
          }

          // 显示成功反馈
          this.modifiedRecently = true
          setTimeout(() => {
            this.modifiedRecently = false
          }, 2000)

          this.editing = false
          this.editingValue = ''
          this.editingError = ''
        } else {
          this.editingError = result.message || '修改失败'
        }
      } catch (error) {
        this.editingError = error.message || '修改失败'
      } finally {
        this.saving = false
      }
    },

    // 处理键盘事件
    handleEditKeydown(event) {
      if (event.key === 'Enter') {
        this.saveEdit()
      } else if (event.key === 'Escape') {
        this.cancelEdit()
      }
    },

    // 高亮搜索关键词
    highlightText(text, keyword) {
      if (!text || !keyword) {
        return this.escapeHtml(String(text || ''))
      }

      const escapedText = this.escapeHtml(String(text))
      const escapedKeyword = keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
      const regex = new RegExp(`(${escapedKeyword})`, 'gi')

      return escapedText.replace(regex, '<mark class="bg-yellow-200 text-gray-900 px-0.5 rounded">$1</mark>')
    },

    // HTML转义，防止XSS
    escapeHtml(text) {
      const div = document.createElement('div')
      div.textContent = text
      return div.innerHTML
    }
  }
}
</script>

<style scoped>
/* 使用 Tailwind CSS 代替大部分样式 */
</style>
